home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / newton / play.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  12KB  |  620 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  * The main loop of Newton (event handling and stuff)
  19.  * Yossi Friedman, 1988
  20.  */
  21.  
  22. #include <stdio.h>
  23. #include <gl.h>
  24. #include <device.h>
  25.  
  26. #include "config.h"
  27. #include "newton.h"
  28. #include "windows.h"
  29. #include "slider.h"
  30.  
  31.  
  32.  
  33. static int playing;
  34.  
  35. /* values for mouse_buttons */
  36. #define LEFT_DOWN    0x010000
  37. #define MIDDLE_DOWN    0x000100
  38. #define RIGHT_ROWN    0x000001
  39. #define LEFT_UP        0x000101
  40. #define MIDDLE_UP    0x010001
  41. #define RIGHT_UP    0x010100
  42.  
  43.  
  44. static int spin_mode = SPIN_MODE_DEFAULT;
  45. #define SPIN_FRAME_ACTION 1
  46.  
  47. extern int auto_mode;
  48.  
  49. void do_inputchange(short val);
  50. void do_redraw(short val);
  51. void do_winquit(short val);
  52. void do_winfreeze(short val);
  53. void do_menu();
  54.  
  55.  
  56. play()
  57. {
  58.     short dev, val;
  59.     int mouse_buttons = 0;
  60.     int spin_frame_count = 0;
  61.     short omx, omy, nmx, nmy;
  62.  
  63. #ifdef STATISTICS
  64. #   define TIMES 100
  65.     long genesis;
  66.     int frame_count = 0;
  67. #endif /* STATISTICS */
  68.  
  69.  
  70.     /* window manager events */
  71.     qdevice(INPUTCHANGE);
  72.     qdevice(REDRAW);
  73.     qdevice(WINQUIT);
  74.     qdevice(WINFREEZE);
  75.     qdevice(WINTHAW);
  76.  
  77.     /* user events */
  78.     qdevice(ESCKEY);
  79.     qdevice(LEFTMOUSE);
  80.     qdevice(MIDDLEMOUSE);
  81.     qdevice(RIGHTMOUSE);
  82.     
  83.     
  84. #ifdef STATISTICS
  85.     time(&genesis);
  86. #endif /* STATISTICS */
  87.  
  88.     /*
  89.      * initialization.  order matters.
  90.      */
  91.     initialize_models();
  92.     initialize_menus();
  93.  
  94.     for (playing = 1; playing;) {
  95.     
  96.     if (auto_mode) {
  97.         spin_mode = 1;
  98.         start_gravity();
  99.     }
  100.  
  101.     /* check events */
  102.     while(qtest()) {
  103.         dev=qread(&val);
  104.  
  105.         /*
  106.          * handle window manager events separately
  107.          */
  108.         switch (dev) {
  109.  
  110.           case INPUTCHANGE:
  111.         do_inputchange(val);
  112.             continue;
  113.  
  114.           case REDRAW:
  115.         do_redraw(val);
  116.         continue;
  117.  
  118.           case WINQUIT:
  119.         do_winquit(val);
  120.         continue;
  121.  
  122.           case WINFREEZE:
  123.         do_winfreeze(val);
  124.         continue;
  125.  
  126.           case WINTHAW:
  127.         /* is supposed to be handled by do_winfreeze */
  128.         fprintf(stderr, "newton: Unexpected WINTHAW (val = %d)\n", val);
  129.         continue;
  130.         }
  131.  
  132.  
  133.  
  134.         /*
  135.          * handle user events
  136.          */
  137.         
  138.         
  139.         /* see if it is a slider event */
  140.         if (current_window && current_window->sid >= 0) {
  141.         if (slider_event(current_window->sid, dev, val) == 0)
  142.             close_current_window();
  143.         continue;
  144.         }
  145.  
  146.         /*
  147.          * main window events
  148.          */
  149.         switch(dev) {
  150.         
  151.           case ESCKEY:
  152.         if (!val)
  153.             playing = 0;
  154.         break;
  155.         
  156.           case LEFTMOUSE:
  157.         if (val) {
  158.             build_model(0);
  159.             stop_gravity();
  160.  
  161.             omx = getvaluator(MOUSEX);
  162.             omy = getvaluator(MOUSEY);
  163.  
  164.             mouse_buttons |= LEFT_DOWN;
  165.         }
  166.         else {
  167.             start_gravity();
  168.             mouse_buttons &= LEFT_UP;
  169.         }
  170.  
  171.         break;
  172.         
  173.           case MIDDLEMOUSE:
  174.         if (val) {
  175.             omx = getvaluator(MOUSEX);
  176.             omy = getvaluator(MOUSEY);
  177.  
  178.             mouse_buttons |= MIDDLE_DOWN;
  179.         }
  180.         else
  181.             mouse_buttons &= MIDDLE_UP;
  182.  
  183.         break;
  184.         
  185.           case RIGHTMOUSE:
  186.         if (val)
  187.             do_menu();
  188.         break;
  189.  
  190.           default:
  191.         fprintf(stderr, "newton: Unknown device event (dev = %d, val = %d)\n", dev, val);
  192.         break;
  193.         }
  194.     }
  195.  
  196.         
  197.     if (current_window && current_window->sid >= 0)
  198.         do_slider(current_window->sid);
  199.     
  200.     if (mouse_buttons) {
  201.         nmx = getvaluator(MOUSEX);
  202.         nmy = getvaluator(MOUSEY);
  203.         reorient(mouse_buttons, 2*(nmx - omx), 2*(nmy - omy));
  204.         omx = nmx;
  205.         omy = nmy;
  206.     }
  207.  
  208.         if (spin_mode && ++spin_frame_count == SPIN_FRAME_ACTION) {
  209.         spin_frame_count = 0;
  210.         reorient(
  211.         MIDDLE_DOWN,
  212.         (getvaluator(MOUSEX) - 640)/6,
  213.         (getvaluator(MOUSEY) - 512)/5
  214.         );
  215.     }
  216.  
  217.     draw_everything();
  218.     iterate();
  219.  
  220. #ifdef STATISTICS
  221.     if ((++frame_count % TIMES) == 0)
  222.         printf("Average: %f frames per second\n",
  223.            (float) frame_count / (float)(time(0) - genesis));
  224. #endif /* STATISTICS */
  225.     
  226.     }
  227. }
  228.  
  229.  
  230. /*
  231.  * window manager event handlers
  232.  */
  233.  
  234. void
  235. do_inputchange(short val)
  236. {
  237.     if (val == 0) {
  238.     current_window = NULL;
  239.     return;
  240.     }
  241.         
  242.     /* search which window was entered */
  243.     for (
  244.     current_window = windows;
  245.     current_window != NULL;
  246.     current_window = current_window->next
  247.     )
  248.     if (current_window->wid == val)
  249.         break;
  250.         
  251. /*
  252.     if (current_window == NULL)
  253.     fprintf(stderr, "newton: Unidentified INPUTCHANGE (val = %d)\n", val);
  254. */
  255.  
  256. }
  257.  
  258. void
  259. do_redraw(short val)
  260. {
  261.     struct window *wp;
  262.     long tmp_wid;
  263.     long size[2];
  264.  
  265.     /* find out which window has to be redrawn */
  266.     for (wp = windows; wp != NULL; wp = wp->next)
  267.     if (wp->wid == val)
  268.         break;
  269.         
  270.     if (wp == NULL) {
  271.     fprintf(stderr, "newton: Unidentified REDRAW (val = %d)\n", val);
  272.     return;
  273.     }
  274.  
  275.     /* is it a slider? */
  276.     if (wp->sid >= 0)
  277.     (void) slider_event(wp->sid, REDRAW, val);
  278.     else {
  279.     tmp_wid = winget();
  280.     winset(wp->wid);
  281.     reshapeviewport();
  282.     if (tmp_wid != -1)
  283.         winset(tmp_wid);
  284.     }
  285.  
  286.     /* get new corners */
  287.     tmp_wid = winget();
  288.     winset(wp->wid);
  289.     getorigin(&(wp->bot_left[X]), &(wp->bot_left[Y]));
  290.     getsize(&size[X], &size[Y]);
  291.     wp->top_right[X] = wp->bot_left[X] + size[X];
  292.     wp->top_right[Y] = wp->bot_left[Y] + size[Y];
  293.     if (tmp_wid != -1)
  294.     winset(tmp_wid);
  295. }
  296.  
  297. void
  298. do_winquit(short val)
  299. {
  300.     struct window *wp;
  301.     long tmp_wid;
  302.  
  303.     /* find out which window was quit */
  304.     for (
  305.     current_window = windows;
  306.     current_window != NULL;
  307.     current_window = current_window->next
  308.     )
  309.     if (current_window->wid == val)
  310.         break;
  311.         
  312.     if (current_window == NULL) {
  313.     fprintf(stderr, "newton: Unidentified WINQUIT (val = %d)\n", val);
  314.     return;
  315.     }
  316.         
  317.     /* is it a slider? */
  318.     if (current_window->sid >= 0) {
  319.     (void)slider_event(current_window->sid, WINQUIT, val);
  320.     close_current_window();
  321.     }
  322.     else
  323.     playing = 0;
  324. }
  325.  
  326. void
  327. do_winfreeze(short val)
  328. {
  329.     struct window *stowed, *wp;
  330.     short dev;
  331.     int i;
  332.     extern void close_model_window(long);
  333.  
  334.     /*
  335.      * -------------------- F R E E Z I N G --------------------
  336.      */
  337.  
  338.     /* find out which window was stowed */
  339.     for (stowed = windows; stowed != NULL; stowed = stowed->next)
  340.     if (stowed->wid == val)
  341.         break;
  342.     
  343.     if (stowed == NULL) {
  344.     fprintf(stderr, "newton: Unindentified WINFREEZE (val = %d)\n", val);
  345.     return;
  346.     }
  347.  
  348.     /* close all windows except for the stowed one */
  349.     for (wp = windows; wp != NULL; wp = wp->next)
  350.     if (wp != stowed)
  351.         if (wp->sid >= 0)
  352.         close_slider(wp->sid);
  353.         else
  354.         close_model_window(wp->wid);
  355.  
  356. #ifdef MP
  357.  
  358.     /* block all the slave processes */
  359.     for (i = 1; i < nproc; i++)
  360.     blockproc(slave_pid[i]);
  361.  
  362. #endif /* MP */
  363.  
  364.  
  365.     /* wait for a WINTHAW */
  366.     while ((dev = qread(&val)) != WINTHAW)
  367.     /* printf("do_winfreeze: got dev = %d, val = %d\n", dev, val) */
  368.     ;
  369.  
  370.  
  371.  
  372.     /*
  373.      * -------------------- T H A W I N G --------------------
  374.      */
  375.  
  376.  
  377.  
  378.     /* open all windows that need to be opened */
  379.     for (wp = windows; wp != NULL; wp = wp->next)
  380.     if (wp != stowed) {
  381.         prefposition(wp->bot_left[X], wp->top_right[X],
  382.              wp->bot_left[Y], wp->top_right[Y]);
  383.         if (wp->sid >= 0)
  384.         wp->wid = open_slider(wp->sid);
  385.         else
  386.         wp->wid = open_model_window("newton");
  387.     }
  388.     else
  389.     if (wp->sid >= 0)
  390.         slider_event(wp->sid, REDRAW, wp->wid);
  391.  
  392. #ifdef MP
  393.  
  394.     /* unblock all slave processes */
  395.     for (i = 1; i < nproc; i++)
  396.     unblockproc(slave_pid[i]);
  397.  
  398. #endif /* MP */
  399.  
  400.  
  401.     find_current_window();
  402. }
  403.  
  404.  
  405. initialize_sliders()
  406. {
  407.     struct slider *sp;
  408.  
  409.     for (sp = sliders; sp < end_sliders; sp++)
  410.     sp->sid = define_slider("Newton", sp->title, sp->lo, sp->hi, sp->dflt, sp->fun);
  411. }
  412.  
  413.  
  414.  
  415. static int
  416.     models_menu,
  417.     physics_menu,
  418.     model_draw_menu,
  419.     wall_draw_menu,
  420.     main_menu;
  421.  
  422. initialize_menus()
  423. {
  424.     char menu_buf[MAX_MENU_ITEMS*MAX_MENU_ITEM_LEN];
  425.     char buf[MAX_MENU_ITEM_LEN], *p, *q;
  426.     int i;
  427.  
  428.     /* make the models menu */
  429.     for (p = menu_buf, i = 0; model_names + i != end_model_names; i++) {
  430.     sprintf(buf,
  431.             (i == 0)? "Models %%t|%s %%x%d": "|%s %%x%d",
  432.             model_names[i], 101 + i);
  433.     for (q = buf; *q; *p++ = *q++)
  434.         ;
  435.     }
  436.     *p = 0;
  437.     models_menu = defpup(menu_buf);
  438.     
  439.     /* make the physics menu */
  440.     for (p = menu_buf, i = 0; i < end_sliders - sliders; i++) {
  441.     sprintf(buf,
  442.             (i == 0)? "Physics %%t|%s %%x%d": "|%s %%x%d",
  443.             sliders[i].title, 201 + i);
  444.     for (q = buf; *q; *p++ = *q++)
  445.         ;
  446.     }
  447.     *p = 0;
  448.     physics_menu = defpup(menu_buf);
  449.  
  450.     /* make the model draw menu */
  451.     model_draw_menu = defpup(
  452. #ifdef HAS_BLENDING
  453.       "Model Display %t|flat surfaces %x301|smooth surfaces %x302|springs %x303|toggle translucency %x304|toggle surfaces+springs %x305|Bermuda %x306"
  454. #else /* HAS_BLENDING */
  455.       "Model Display %t|flat surfaces %x301|smooth surfaces %x302|springs %x303|toggle surfaces+springs %x305|Bermuda %x306"
  456. #endif /* HAS_BLENDING */
  457.     );
  458.  
  459.     /* make the wall draw menu */
  460.     wall_draw_menu = defpup("Room Display %t|lighted walls w/ shadows %x401|lighted walls w/o shadows %x402|pinball walls %x403");
  461.  
  462.     /* force main menu to be generated */
  463.     main_menu = 0;
  464. }
  465.  
  466.  
  467. void
  468. do_menu()
  469. {
  470.     int val;
  471.     struct window *wp;
  472.     int sid;
  473.     
  474.     if (main_menu == 0) {
  475.     main_menu = defpup("Newton %t| models %m|physics %m|model display %m|room display %m",
  476.                models_menu, physics_menu, model_draw_menu, wall_draw_menu);
  477.     addtopup(main_menu, spin_mode? "spin mode off": "spin mode on");
  478.     addtopup(main_menu, "exit");
  479.     }
  480.  
  481.     val = dopup(main_menu);
  482.  
  483.     if (val > 400)
  484.     /* wall draw menu */
  485.     switch (val) {
  486.       case 401:
  487.         draw_wall = draw_lighted_wall;
  488.         shadows_too = 1;
  489.         break;
  490.  
  491.       case 402:
  492.         draw_wall = draw_lighted_wall;
  493.         shadows_too = 0;
  494.         break;
  495.  
  496.       case 403:
  497.         draw_wall = draw_pinball_wall;
  498.         break;
  499.     }
  500.         
  501.     if (val > 300)
  502.     /* model draw menu */
  503.     switch (val) {
  504.       case 301:
  505.         draw_model = draw_flat_surfs;
  506.         if (mode != RGB) {
  507.             mode = RGB;
  508.             RGBmode();
  509.             gconfig();
  510.         }
  511.         break;
  512.  
  513.       case 302:
  514.         draw_model = draw_smooth_surfs;
  515.         if (mode != RGB) {
  516.             mode = RGB;
  517.             RGBmode();
  518.             gconfig();
  519.         }
  520.         break;
  521.  
  522.       case 303:
  523.         draw_model = draw_springs;
  524.         if (mode != RGB) {
  525.             mode = RGB;
  526.             RGBmode();
  527.             gconfig();
  528.         }
  529.         break;
  530.  
  531. #ifdef HAS_BLENDING
  532.       case 304:
  533.         alpha_blended = 1 - alpha_blended;
  534.         break;
  535. #endif /* HAS_BLENDING */
  536.  
  537.       case 305:
  538.         springs_too = 1 - springs_too;
  539.         break;
  540.         
  541.       case 306:
  542.         draw_model = draw_flat_surfs;
  543.         if (mode != COLOR_MAP) {
  544.             mode = COLOR_MAP;
  545.             cmode();
  546.             gconfig();
  547.         }
  548.         break;
  549.     }
  550.     else
  551.     if (val > 200) {
  552.     /* physics menu */
  553.     if (&sliders[val - 201] >= end_sliders) {
  554.         fprintf(stderr, "newton: Unknown physics menu selection\n");
  555.         return;
  556.     }
  557.  
  558.     sid = sliders[val - 201].sid;
  559.     for (wp = windows; wp != NULL; wp = wp->next)
  560.         if (wp->sid == sid) {
  561.         /* window already open */
  562.         (void) open_slider(sid);
  563.         break;
  564.         }
  565.  
  566.     if (wp == NULL)
  567.         new_window(open_slider(sid), sid);
  568.  
  569.     find_current_window();
  570.     }
  571.     else
  572.     if (val > 100) {
  573.     /* models menu */
  574.     model_index = val - 101;
  575.     build_model(1);
  576.     stop_gravity();
  577.     }
  578.     else
  579.     /* main menu */
  580.     switch (val) {
  581.       case -1:
  582.         break;
  583.  
  584.       case 5:
  585.         spin_mode = (spin_mode == 0);
  586.  
  587.         /* force regeneration of main menu */
  588.         freepup(main_menu);
  589.         main_menu = 0;
  590.         break;
  591.         
  592.       case 6:
  593.         playing = 0;
  594.         break;
  595.  
  596.       default:
  597.         fprintf(stderr, "newton: Unknown menu selection (%d)\n", val);
  598.         break;
  599.     }
  600. }
  601.  
  602.  
  603. reorient(mouse_buttons, dx, dy)
  604.     int mouse_buttons;
  605.     int dx, dy;
  606. {
  607.     if (mouse_buttons & LEFT_DOWN) {
  608.     rotate_model((Angle) dx, 'Y');
  609.     rotate_model((Angle)-dy, 'X');
  610.     }
  611.  
  612.     if (mouse_buttons & MIDDLE_DOWN) {
  613.     rotate_graphics((Angle) dx, 'Y');
  614.     rotate_physics ((Angle)-dx, 'Y');
  615.  
  616.     rotate_graphics((Angle)-dy, 'X');
  617.     rotate_physics ((Angle) dy, 'X');
  618.     }
  619. }
  620.